home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Libraries / SAT / HeartQuest sample ƒ / main.p < prev    next >
Encoding:
Text File  |  1993-09-19  |  7.7 KB  |  272 lines  |  [TEXT/PJMM]

  1. {================================================}
  2. {=============== HeartQuest main unit ================}
  3. {================================================}
  4.  
  5. { Example file for Ingemars Sprite Animation Toolkit. }
  6. { © Ingemar Ragnemalm 1992 }
  7. { See doc files for legal terms for using this code. }
  8.  
  9. { HeartQuest is a very simple game demonstrating how to use the Sprite Animation}
  10. { Toolkit. I originally wrote the game as my present to my wife Eva for Valentine's}
  11. { day 1992. You can still tell that this file once started as the Skel example in the}
  12. { TransSkel package by Paul duBois. }
  13.  
  14. { This "main" file is rather small, and holds very little game specific code.}
  15. { Its main concern is to initialize the various parts of the game, and to hold the}
  16. { file and edit menu handlers. }
  17.  
  18. program HeartQuest;
  19.  
  20.     uses
  21.         TransSkel, SAT, GameGlobals, GameWind, {sound,}
  22.         SoundConst, scores, CenterStuff;
  23.  
  24. {Variables for the main program}
  25.     var
  26.         keys: KeyMap;
  27.         ZoomFlag: Boolean;
  28.         ignore: longint; {For UnloadScrap error}
  29.  
  30. { -------------------------------------------------------------------- }
  31. {                        Menu handling procedures                        }
  32. { -------------------------------------------------------------------- }
  33.  
  34. {    Handle selection of "About…" item from Apple menu}
  35.  
  36.     procedure DoAbout;
  37.         var
  38.             h: StringHandle;
  39.             ignore: integer;
  40.     begin
  41. {SetParamText(aboutStr);}
  42.         ignore := DoAlert(43, aboutAlrt, nil);
  43.     end;
  44.  
  45. {    Process selection from File menu.}
  46.  
  47. {    HelpEnemies    Shows a help box. }
  48. {    Quit    Request a halt by calling SkelHalt().  This makes SkelMain}
  49. {            return.}
  50.  
  51.     procedure DoFileMenu (item: integer);
  52.         var
  53.             ignore: integer;
  54.     begin
  55.         case item of
  56.             helpenemies: 
  57.                 ignore := DoAlert(43, helpenemiesAlrt, nil);
  58.             quit: 
  59.                 begin
  60.                     if pauseFlag then
  61.                         DoGameOver;
  62.                     SkelWhoa;
  63.                 end;
  64.             otherwise
  65.                 ;
  66.         end;
  67.     end;
  68.  
  69.     procedure DoEditMenu;
  70.     begin
  71.     end;
  72.  
  73. {    Initialize menus.  Tell TransSkel to process the Apple menu}
  74. {    automatically, and associate the proper procedures with the}
  75. {    File and Edit menus.}
  76.  
  77.     procedure SetUpMenus;
  78.     begin
  79.         SkelApple('About HeartQuest…', @DoAbout);
  80.         fileMenu := GetMenu(fileMenuRes);
  81.         editMenu := GetMenu(editMenuRes);
  82.         GameMenu := GetMenu(GameMenuRes);
  83.         highMenu := GetMenu(highMenuRes);
  84.         dummy := SkelMenu(fileMenu, @DoFileMenu, nil, false);
  85.         dummy := SkelMenu(editMenu, @DoEditMenu, nil, false);
  86.         dummy := SkelMenu(GameMenu, @DoGameMenu, nil, false);
  87.         dummy := SkelMenu(highMenu, @DoHighMenu, nil, true);
  88.     end;
  89.  
  90. { Initialize settings resources. These are saved in the game file itself. This is elegant,}
  91. { but a bit "server-hostile". An alternative is to create a preference file in the system}
  92. { folder. }
  93.  
  94.     procedure InitSettings;
  95.     begin
  96.         features := featHnd(GetResource('Feat', 0));        { Load the settings }
  97.         if features = nil then                                { Settings doesn't exist; create new }
  98.             begin
  99.                 features := featHnd(NewHandle(Sizeof(featRec)));
  100.                 CheckNoMem(Ptr(features));
  101.                 features^^.sound := true;
  102.                 features^^.allowBG := false;
  103.                 features^^.player := 'Anonymous';
  104.                 features^^.macho := false;
  105.                 AddResource(handle(features), 'Feat', 0, 'Settings');
  106.             end;
  107. { Fix all checkmarks in the menus }
  108.         if features^^.sound then
  109.             begin
  110.                 features^^.sound := false;
  111.                 DoGameMenu(sound);
  112.             end
  113.         else
  114.             begin
  115.                 features^^.sound := true;
  116.                 DoGameMenu(sound);
  117.             end;
  118.         if features^^.macho then
  119.             begin
  120.                 features^^.macho := false;
  121.                 DoGameMenu(macho);
  122.             end
  123.         else
  124.             begin
  125.                 features^^.macho := true;
  126.                 DoGameMenu(macho);
  127.             end;
  128.         if features^^.PlotFast then
  129.             begin
  130.                 features^^.PlotFast := false;
  131.                 DoGameMenu(FastAnimation);
  132.             end
  133.         else
  134.             begin
  135.                 features^^.PlotFast := true;
  136.                 DoGameMenu(FastAnimation);
  137.             end;
  138.         if features^^.allowBG then
  139.             begin
  140.                 features^^.allowBG := false;
  141.                 DoGameMenu(allowBG);
  142.             end
  143.         else
  144.             begin
  145.                 features^^.allowBG := true;
  146.                 DoGameMenu(allowBG);
  147.             end;
  148.     end;
  149.  
  150. { Hide gameWindow on suspend, so the user can get access to disk icons etc. }
  151.  
  152.     procedure DoSuspendResume (b: boolean);
  153.     begin
  154.         if b then
  155.             begin
  156.                 showwindow(gameWind);
  157.                 selectwindow(gameWind);
  158.             end
  159.         else
  160.             hidewindow(gameWind)
  161.     end;
  162.  
  163.     function DoEvt (e: eventRecord): boolean;
  164.     begin
  165.         if e.what = OSevt then
  166.             begin
  167.                 if BAND(BROTL(e.message, 8), $FF) = SuspendResumeMessage then
  168.                     DoSuspendResume(BAnd(e.message, 1) <> 0);
  169.                 DoEvt := true;
  170.             end
  171.         else
  172.             DoEvt := false;
  173.     end; (* end DoEvent *)
  174.  
  175.  
  176. {Do a quick approximation of how much memory we need.}
  177.     function GetMemoryDemand: Longint;
  178.         const
  179.             FaceCount = 19;
  180.             SpriteCount = 30; {We can get *lots* of sprites in this game!}
  181.         var
  182.             theWorld: SysEnvRec;
  183.             error: OSerr;
  184.             TestDepth, TestHeight, TestWidth: Longint;
  185.             OffScreenMem, FaceMem: Longint;
  186.     begin
  187. {SAT will set the ColorFlag later, but we set it right now since we want to check the screen depth}
  188. {before SAT knows what screen it will use.}
  189.         error := SysEnvirons(1, theWorld);
  190.         if error = noErr then
  191.             ColorFlag := theWorld.hasColorQD
  192.         else
  193.             ColorFlag := false; {If SysEnvirons won't work, let's assume we don't have color.}
  194.  
  195.         if ColorFlag then
  196.             TestDepth := GetMainDevice^^.gdPMap^^.pixelSize
  197.         else
  198.             TestDepth := 1;
  199.  
  200. {Dimensions of game area, zoom or not, plus extra margins}
  201.         if ZoomFlag then
  202.             begin
  203.                 TestHeight := GetMainDevice^^.gdPMap^^.bounds.bottom - GetMainDevice^^.gdPMap^^.bounds.top + 128;
  204.                 TestWidth := GetMainDevice^^.gdPMap^^.bounds.right - GetMainDevice^^.gdPMap^^.bounds.left + 128;
  205.             end
  206.         else
  207.             begin
  208.                 TestHeight := 322 + 128;
  209.                 TestWidth := 512 + 128;
  210.             end;
  211.  
  212. {Sum an approximation of the amount of memory needed.}
  213. {Many calculations are not simplified below for clarity}
  214. {Note that many small memory structures are not counted, so we have to reserve a bit extra}
  215. {in the end.}
  216.  
  217.         OffScreenMem := TestDepth * TestHeight * TestWidth div 8; {Size of pixel data of one offscreen buffer.}
  218.         FaceMem := (32 * 32 * TestDepth div 8) + sizeof(Sprite);
  219.         if TestDepth = 4 then
  220.             FaceMem := FaceMem * 2; {In 4 bits, we need a bit more, close to twice the amount}
  221.  
  222.         GetMemoryDemand := 2 * OffScreenMem + FaceCount * FaceMem + SpriteCount * sizeof(sprite);
  223.     end;
  224.  
  225. { -------------------------------------------------------------------- }
  226. {                                    Main                                }
  227. { -------------------------------------------------------------------- }
  228.  
  229. begin
  230.     SkelInit(6, nil);                { initialize }
  231.     SetUpMenus;                { install menu handlers }
  232.  
  233. {Is the user holding down a modifier key? If so, we should use the whole screen.}
  234.     GetKeys(keys);
  235.     ZoomFlag := keys[55] or keys[56] or keys[58] or keys[59]; {cmd, shift, alt, ctrl}
  236.  
  237. {Before starting, check if we have enough memory! UnloadScrap, check depth and dimensions against FreeMem}
  238.     ignore := UnloadScrap; {Ignore any error}
  239.  
  240.     if GetMemoryDemand + 50000 > FreeMem then {Unreasonably little memory!}
  241.         begin
  242.             ReportStr('Too little memory. Give me some more (or use fewer colors).');
  243.             halt; {We can quit without any cleanup. (I.e. we havn't allocated any sound channel.)}
  244.         end;
  245.  
  246.     ConfigureSAT(true, VPositionSort, KindCollision, 32);
  247. { Initialize the Sprite Animation Toolkit, set up offscreen buffers and make the window. }
  248.  
  249.     if ZoomFlag then {if cmd, shift, alt, ctrl}
  250.         gameWind := InitSAT(0, 0, 32000, 32000) {132, 133}
  251.     else
  252.         gameWind := InitSAT(0, 0, 512, 322); {132, 133}
  253.  
  254. { Init all the different parts of the game. }
  255.     GameWindInit;    { Init the game window }
  256.     loadsounds;        { preload all sound resources }
  257.     initScores;        { Init the score module }
  258.     InitSettings;    { Load the settings }
  259.  
  260. { Set the randseed to something that is random enough. }
  261.     randSeed := TickCount;
  262.  
  263. {    SetPort(gameWind);}
  264. {    BackColor(WhiteColor);}
  265. {    Invalrect(gameWind^.portrect);}
  266.  
  267.     SkelEventHook(@DoEvt); { handle MultiFinder-events }
  268.  
  269.     SkelMain;                { loop 'til Quit selected }
  270.     SkelClobber;                { clean up }
  271.     SATSoundShutUp;            { Terminate sounds }
  272. end.